package wrapper

import (
	"context"
	"fmt"
	"github.com/micro/go-micro/v2/server"
	context2 "kop/framework/context"
	"kop/framework/errors"
	"kop/pb"
	"kop/util/log"
	"time"
)

func NewLogWrapper(fn server.HandlerFunc) server.HandlerFunc {

	return func(ctx context.Context, req server.Request, rsp interface{}) (err error) {

		log.Info("Request [%s], [%v]", req.Method(), req.Body())

		var sTime = time.Now()

		defer func() {

			if r := recover(); r != nil {

				switch e := r.(type) {
				case error:
					err = e
				case string:
					err = fmt.Errorf(e)
				default:
					err = fmt.Errorf("%v", e)
				}
			}

			if err != nil {

				err = errors.Parse(err)

				log.Error("[%s]<%v> Error: %s", req.Method(), req.Body(), errors.Parse(err).Detail)
			}
		}()

		var user pb.User
		if user, err = context2.GetUser(ctx); err != nil {
			ctx = context2.WithUser(ctx, user)
		}

		if err = fn(ctx, req, rsp); err == nil {

			log.Info("[%s] Success, [%d] milliseconds", req.Method(), time.Now().Sub(sTime).Milliseconds())
		}

		return err
	}
}
